Vue.component('project-region-editor', {
    props: {
        projectId: {
            type: Number,
            default: 0,
        },
        showCancel: {   //是否显示取消按钮
            type: Boolean,
            default: false,
        },
        showDelete: {   //是否显示删除按钮
            type: Boolean,
            default: false,
        },
        readonly: { //是否只读，true:不显示相关编辑按钮
            type: Boolean,
            default: false,
        }
    },
    data() {
        return {
            map: null,
            draw: null,
            loaded: false,
            projectFeatures: null,
            drawType: 0, // 1: 调整位置, 2: 重绘
            isEditing: false,   // 是否处于编辑状态
            isDrawing: false,   //是否正在绘制多边形
            selectFeatureId: null,  //绘制时，当前选中的多边形
            projectMarker: null,
            regionCode: 0,
            placeSearch: null,
            placeSearchLoading: false,
            placeList: [],
            selectPlace: ''
        }
    },
    template: `
    <div class="project-region-editor">
        <div class="region-editor-container" id="regionEditorMapContainer"></div>
        <div v-if="placeSearch" class="region-editor-search">
            <el-select size="small" v-model="selectPlace" placeholder="请输入关键字" filterable remote clearable
                :remote-method="searchPlace" :loading="placeSearchLoading" 
                @change="selectPlaceChange">
                <el-option v-for="item in placeList" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
        </div>
        <div class="region-editor-buttons" v-show="loaded && !readonly">
            <template v-if="!isEditing">
                <template v-if="projectFeatures">
                    <slot name="position" :position="position"><el-button size="small" @click="position">调整位置</el-button></slot>
                    <slot name="redraw" :redraw="redraw"><el-button size="small" @click="redraw">重新绘制</el-button></slot>
                </template>
                <template v-else>
                    <slot name="redraw" :redraw="redraw"><el-button size="small" @click="redraw">编辑位置</el-button></slot>
                </template>
            </template>
            <template v-if="isEditing">
                <slot name="confirm" :confirm="confirm"><el-button size="small" @click="confirm">确　　定</el-button></slot>
                <template v-if="showCancel">
                    <slot name="cancel" :cancel="cancel"><el-button size="small" @click="cancel">取　　消</el-button></slot>
                </template>
                <template v-if="showDelete && selectFeatureId">
                    <slot name="delete" :delete="deleteSelectPolygon"><el-button size="small" @click="deleteSelectPolygon">删　　除</el-button></slot>
                </template>
            </template>
        </div>
    </div>
    `,
    mounted() {
        this.createStyle();
        this.initMap().then(()=>{
            this.initDraw();
            if(this.projectId) {
                return this.initProjectLayer();
            }else {
                return this.initCurrentRegionBounds();
            }
        }).then(()=>{
            if(this.projectId) {
                this.initProjectCenterMarker();
            }
            this.loaded = true;
            return this.initAMapSearchPlugin();
        }).then(()=>{

        }).catch(e => {
            this.$message.error(e);
        });
    },
    watch: {
        isEditing(flag) {
            //console.log('isEditing === >', flag);
            if(flag) {
                this.hideProjectMarker();
            }else {
                this.showProjectMarker();
            }
        }
    },
    methods: {
        initMap() {
            return new Promise((resolve, reject) => {
                if(!window.mapboxgl) {
                    reject('请引入mapbox-gl.js');
                    return;
                }
                if(!window.MapboxDraw) {
                    reject('请引入mapbox-gl-draw.js');
                    return;
                }
                if(!window.turf) {
                    reject('请引入turf.min.js');
                    return;
                }
                this.$nextTick(() => {
                    this.getCenter().then(center => {
                        let mapStyle = {
                            "version": 8,
                            "sources": {
                            },
                            "layers": []
                        };
                        if(GLOBAL_CONFIG.mapGlyphs){
                            mapStyle["glyphs"] = GLOBAL_CONFIG.mapGlyphs;
                        }
                        this.map = new mapboxgl.Map({
                            container: document.getElementById('regionEditorMapContainer'),
                            center: center,
                            zoom: 12,
                            minzoom: 0,
                            maxzoom: 18,
                            doubleClickZoom: false,
                            style: mapStyle,
                        });
                        this.map.on('load', () => {
                            this.initTiandituLayers();
                            resolve();
                        });
                        //错误处理:控制台不打印错误
                        this.map.on('error', (e)=>{
                        });
                    });
                });
            });
        },
        /**
         * 初始高德地图搜索插件
         * @returns {Promise<unknown>}
         */
        initAMapSearchPlugin() {
            return new Promise((resolve, reject) => {
                if(this.regionCode) {
                    if(!window.AMapLoader) {
                        reject('请引入https://webapi.amap.com/loader.js');
                        return;
                    }
                    AMapLoader.load({
                        key: GLOBAL_CONFIG.amapKey,//首次load key为必填
                        version:'2.0',
                        plugins: ["AMap.PlaceSearch"]
                    }).then(()=>{
                        let regionCode = this.regionCode+"";
                        regionCode = regionCode.substring(0,4)+'00';
                        this.placeSearch = new AMap.PlaceSearch({
                            city: Number(regionCode),
                        });
                        resolve();
                    }).catch((e) => {
                        reject(e);
                    });
                }else {
                    reject();
                }
            });
        },
        /**
         * 地址搜素
         * @param query
         */
        searchPlace(query) {
            this.placeSearchLoading = true;
            this.placeSearch.search(query, (status, result) => {
                this.placeSearchLoading = false;
                if (status === 'complete' && result.info === 'OK') {
                    this.placeList = result.poiList.pois;
                }else {
                    this.placeList = [];
                }
            });
        },
        /**
         * 地址选择后定位到该地址所在经纬度
         */
        selectPlaceChange(addressId) {
            if(addressId) {
                let place = this.placeList.find(item => item.id===addressId);
                if(place) {
                    let {lat, lon} = GPS.gcj_decrypt_exact(place.location.lat, place.location.lng); //高德地图坐标转GPS坐标
                    this.map.flyTo({
                        center: [lon, lat],
                        zoom: 15
                    });
                }
            }
        },
        /**
         * 天地图瓦片底图相关图层
         */
        initTiandituLayers() {
            let imgRasterLayer = "imgRaster";
            let imgTiles = this.tiandituTiles('img');
            let ciaTiles = this.tiandituTiles('cia');
            this.map.addSource(imgRasterLayer, {
                type: 'raster',
                tiles: imgTiles,
                tileSize: 256,
            });
            this.map.addLayer({
                id: imgRasterLayer,
                type: 'raster',
                source: imgRasterLayer,
                paint: {'raster-opacity': 1},
                minzoom: 0,
                maxzoom: 18,
                zIndex: 1,
            });
            let ciaRasterLayer = "ciaRaster";
            this.map.addSource(ciaRasterLayer, {
                type: 'raster',
                tiles: ciaTiles,
                tileSize: 256,
            });
            this.map.addLayer({
                id: ciaRasterLayer,
                type: 'raster',
                source: ciaRasterLayer,
                paint: {'raster-opacity': 1},
                minzoom: 0,
                maxzoom: 18,
                zIndex: 2,
            });
        },
        /**
         * 获取地图初始时的中心点
         * @returns {Promise<unknown>}
         */
        getCenter() {
            return new Promise(resolve => {
                if(GLOBAL_CONFIG.gisCenter && GLOBAL_CONFIG.gisCenter.lng && GLOBAL_CONFIG.gisCenter.lat) {
                    resolve([GLOBAL_CONFIG.gisCenter.lng, GLOBAL_CONFIG.gisCenter.lat]);
                }else {
                    tpHttp.post(this, 'action=com.top.hsfpl.onePic.postgis.config', {}, (data, code, msg)=>{
                        if(code===0 && data.longitude && data.latitude)  {
                            resolve([data.longitude, data.latitude]);
                        }else {
                            resolve([119.470817240586,29.9001812750694]);
                        }
                    });
                }
            });
        },
        /**
         * 天地图瓦片WMTS地址
         * @param layerType: img、cia
         * @returns {*[]}
         */
        tiandituTiles(layerType) {
            let tiles = [];
            for (let i = 0; i < 8; i++) {
                let url = `https://t${i}.tianditu.gov.cn/${layerType}_w/wmts?tk=${GLOBAL_CONFIG.tiandituKey}&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${layerType}&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles`;
                tiles.push(url);
            }
            return tiles;
        },
        /**
         * 初始地图多边形编辑器
         */
        initDraw() {
            this.draw = new MapboxDraw({
                displayControlsDefault: false,
                controls: {}
            });
            this.map.addControl(this.draw);
            this.map.on('draw.create', (e) => {
                //console.log('draw.create', e);
                let createdFeature = e.features[0];
                if(this.checkPolygonSelfIntersection(createdFeature)) {
                    this.$message.error('多边形存在自相交，请重新绘制');
                    this.draw.delete(createdFeature.id);
                }
                setTimeout(()=> {//切换模式为simple_select，用于选择多边形
                    this.isDrawing = false;
                    this.draw.changeMode('simple_select');
                }, 100);
            });
            this.map.on('draw.selectionchange', (e)=>{
                //console.log('draw.selectionchange ==> ',e);
                if(e.features.length>0) {
                    //删除选中的多边形
                    this.selectFeatureId = e.features[0].id;
                }else {
                    this.selectFeatureId = null;
                }
            });
            this.map.on('click', (e) => {
                if(this.isEditing && this.drawType===2) {
                    //重新绘制模式下，画完一个，自动进入绘制多边形模式，可继续绘制，并且可对其他多边形编辑
                    if(!this.isDrawing) {
                        let point = turf.point([e.lngLat.lng, e.lngLat.lat]);
                        let features = this.draw.getAll().features;
                        let clickedPolygon = false;
                        for (let feature of features) {
                            if(turf.booleanPointInPolygon(point, feature)) {
                                clickedPolygon = true;
                                this.draw.changeMode('direct_select', { featureId: feature.id });
                                break;
                            }
                        }
                        if(!clickedPolygon) {
                            this.startDrawPolygon(e);
                        }
                    }
                }
            });
        },
        /**
         * 开始绘制多边形
         * @param e
         */
        startDrawPolygon(e) {
            this.isDrawing = true;
            // 开始绘制新的多边形
            this.draw.changeMode('draw_polygon');
            // 模拟在点击位置的鼠标事件
            setTimeout(()=> {
                var drawCanvas = this.map.getCanvas();
                var rect = drawCanvas.getBoundingClientRect();
                var x = e.point.x + rect.left;
                var y = e.point.y + rect.top;
                var clickEvent = new MouseEvent('mousedown', {
                    clientX: x,
                    clientY: y,
                    bubbles: true,
                    cancelable: true
                });
                drawCanvas.dispatchEvent(clickEvent);
                // 立即触发 mouseup 事件以确保点被放置
                var mouseupEvent = new MouseEvent('mouseup', {
                    clientX: x,
                    clientY: y,
                    bubbles: true,
                    cancelable: true
                });
                drawCanvas.dispatchEvent(mouseupEvent);
            }, 0);
        },
        /**
         * 初始项目的区域图层
         */
        initProjectLayer() {
            return new Promise(resolve => {
                let param = {project_id: this.projectId};
                tpHttp.post(this, 'action=com.top.hsfpl.onePic.project.detail', {param:JSON.stringify(param)}, (data, code, msg)=>{
                    if(code===0 && data && data.area_id) {
                        this.regionCode = data.area_id;
                        if(data.polygon) {
                            let polygon = JSON.parse(data.polygon);
                            let combineFeature = turf.feature(polygon);
                            //combineFeature里是一个MultiPolygon，包含多个多边形
                            //turf.flattenEach 去除每个多边形
                            let features = [];
                            turf.flattenEach(combineFeature, (currentFeature, featureIndex, multiFeatureIndex) => {
                                features.push(currentFeature);
                            });
                            this.projectFeatures = turf.featureCollection(features)
                            this.addProjectLayer();
                            let boundBox = turf.bbox(this.projectFeatures);
                            this.map.fitBounds(boundBox, {
                                padding: {top: 20, bottom: 20},
                            });
                        }
                    }
                    resolve();
                });
            });
        },
        /**
         * 初始项目中心点标记
         */
        initProjectCenterMarker() {
            let param = {project_id: this.projectId};
            tpHttp.post(this, 'action=com.top.hsfpl.onePic.project.center', {param:JSON.stringify(param)}, (data, code, msg)=>{
                if(code===0 && data) {
                    let {longitude, latitude} = data;
                    if(longitude && latitude) {
                        this.resetProjectMarker(longitude, latitude);
                    }
                }
            });
        },
        /**
         * 重置项目中心点标记
         * @param longitude
         * @param latitude
         */
        resetProjectMarker(longitude, latitude) {
            if(this.projectMarker) {
                this.projectMarker.setLngLat([longitude, latitude]);
            }else {
                let draggable = !this.readonly;
                this.projectMarker = new mapboxgl.Marker({
                    draggable: draggable,
                });
                this.projectMarker.setLngLat([longitude, latitude]).addTo(this.map);
                if(draggable) {
                    this.projectMarker.on('dragend', () => {
                        let lngLat = this.projectMarker.getLngLat();
                        //console.log('点标记经纬度==> ', lngLat)
                        this.$emit('center-change', {longitude: Number(lngLat.lng.toFixed(6)), latitude: Number(lngLat.lat.toFixed(6))});
                    });
                }
            }
        },
        showProjectMarker() {
            if(this.projectMarker) {
                this.projectMarker.getElement().style.visibility = 'visible';
            }
        },
        hideProjectMarker() {
            if(this.projectMarker) {
                this.projectMarker.getElement().style.visibility = 'hidden';
            }
        },
        /**
         * 初始当前账号主体所在区域边界
         */
        initCurrentRegionBounds() {
            return new Promise(resolve => {
                this.getCurrentRegionCode().then(regionCode => {
                    if(regionCode) {
                        this.regionCode = regionCode;
                        return this.getRegionGeojson(regionCode);
                    }else {
                        return Promise.resolve(null);
                    }
                }).then(geojson => {
                    if(geojson) {
                        let boundBox = turf.bbox(geojson);
                        this.map.fitBounds(boundBox, {
                            padding: {top: 20, bottom: 20},
                        });
                    }
                    resolve();
                });
            });
        },
        /**
         * 获取当前账号主体所在区域编码
         * @returns {Promise<unknown>}
         */
        getCurrentRegionCode() {
            return new Promise(resolve => {
                tpHttp.post(this, 'action=com.top.hsfpl.onePic.region.list', {param:JSON.stringify({parent_id:0})}, (data, code, msg) => {
                    if(code===0 && data && data.length>0) {
                        resolve(data[0].area_id);
                    }else {
                        resolve(null);
                    }
                });
            });
        },
        /**
         * 获取指定区域编码的geojson
         * @param regionCode
         * @returns {Promise<unknown>}
         */
        getRegionGeojson(regionCode) {
            return new Promise(resolve => {
                tpHttp.post(this, 'action=com.top.hsfpl.onePic.region.geom', {param:JSON.stringify({region_code:regionCode})}, (data, code, msg) => {
                    if(code===0 && data && data.type) {
                        resolve(data);
                    }else {
                        resolve(null);
                    }
                });
            });
        },
        /**
         * 添加编辑的项目图层
         */
        addProjectLayer() {
            if(this.projectFeatures) {
                let layerName = 'project-layer';
                this.map.addSource(layerName, {
                    'type': 'geojson',
                    'data': this.projectFeatures
                });
                this.map.addLayer({
                    'id': layerName,
                    'type': 'fill',
                    'source': layerName,
                    'layout': {},
                    'paint': {
                        'fill-color': '#00A0E9',
                        'fill-opacity': 0.5
                    }
                });
                this.map.addLayer({
                    'id': layerName+'-bound',
                    'type': 'line',
                    'source': layerName,
                    'layout': {},
                    'paint': {
                        'line-width': 3,
                        'line-color': '#00A0E9',
                        'line-opacity': 1
                    }
                });
            }
        },
        /**
         * 移除项目图层
         */
        removeProjectLayer() {
            let layerName = 'project-layer';
            if(this.map.getLayer(layerName)) {
                this.map.removeLayer(layerName);
                this.map.removeLayer(layerName+'-bound');
            }
            if (this.map.getSource(layerName)) {
                this.map.removeSource(layerName);
            }
        },
        /**
         * 调整位置点击
         */
        position() {
            this.removeProjectLayer();
            if(this.projectFeatures) {
                // 添加多边形到Draw
                this.draw.add(this.projectFeatures);
            }
            // 进入编辑模式
            this.draw.changeMode('simple_select');
            this.drawType = 1;
            this.isEditing = true;
        },
        /**
         * 重新绘制
         */
        redraw() {
            this.removeProjectLayer();
            //this.draw.changeMode('draw_polygon');
            this.drawType = 2;
            this.isEditing = true;
        },
        /**
         * 点击确定
         */
        confirm() {
            // 获取编辑后的多边形
            let features = this.draw.getAll();
            if(features.features.length===0) {
                this.$message.error('未绘制任何图斑');
                return;
            }
            //判断是否有效的多边形
            for(let feature of features.features) {
                if(this.checkPolygonSelfIntersection(feature)) {
                    this.$message.error('存在无效的图斑');
                    return;
                }
            }
            this.projectFeatures = features;
            //console.log(this.projectFeatures);
            let combined = turf.combine(this.projectFeatures);//把多个feature合并成一个
            //console.log(combined);
            let area = turf.area(combined);
            //平方米转亩
            area = area / 666.67;
            //let centerFeature = turf.truncate(turf.center(combined),{precision:6});
            //console.log('centerFeature ==> ', centerFeature);
            let longitude = null;
            let latitude = null;
            /*if(centerFeature && centerFeature.geometry && centerFeature.geometry.coordinates) {
                longitude = centerFeature.geometry.coordinates[0];
                latitude = centerFeature.geometry.coordinates[1];
            }*/
            let maxAreaFeature = null;  //最大面积的feature
            let maxArea = 0;
            for(let feature of features.features) {
                let tmpArea = turf.area(feature);
                if(tmpArea > maxArea) {
                    maxArea = tmpArea;
                    maxAreaFeature = feature;
                }
            }
            if(maxAreaFeature) {//取最大面积feature的中心点，做为项目中心点
                let centerFeature = turf.truncate(turf.center(maxAreaFeature),{precision:6});
                longitude = centerFeature.geometry.coordinates[0];
                latitude = centerFeature.geometry.coordinates[1];
            }

            this.getAddress(features.features).then(address => {
                //待查询多边形中心点经纬度对应的详细地址
                this.resetProjectMarker(longitude, latitude);//重置项目marker位置
                this.$emit('confirm-draw', {polygon: combined.features[0].geometry, acreage: area, longitude, latitude, address});
                this.cancel();
            });
        },
        getAddress(features) {
            let allCenter = [];
            for(let feature of features) {
                let center = turf.center(feature);
                if(center && center.geometry){
                    allCenter.push(turf.truncate(center,{precision:6}));
                }
            }
            return new Promise(resolve => {
                if(allCenter.length>0) {
                    let lnglat_list = allCenter.map(point => point.geometry.coordinates.join(','));
                    tpHttp.post(this, 'action=com.top.hsfpl.onePic.geo.reverse', {param:JSON.stringify({lnglat_list:lnglat_list})}, (data, code, msg)=>{
                        if(code===0 && data && data.length>0) {
                            let allAddress = data.filter(item => item.township).map(item => item.township+""+item.detailAddress);
                            let detailAddress = Array.from(new Set(allAddress)).join(', ');
                            resolve(detailAddress);
                        }else {
                            resolve("");
                        }
                    });
                }else {
                    resolve('');
                }
            });
        },
        /**
         * 点击取消
         */
        cancel() {
            // 删除Draw中的所有要素
            this.draw.deleteAll();
            this.addProjectLayer();
            this.drawType = 0;
            this.isEditing = false;
        },
        /**
         * 点击删除
         */
        deleteSelectPolygon() {
            if(this.isEditing && this.selectFeatureId) {
                this.draw.delete(this.selectFeatureId);
                this.selectFeatureId = null;
            }
        },
        /**
         * 判断多边形是否自相交
         * @param feature
         * @returns {boolean}
         */
        checkPolygonSelfIntersection(feature) {
            const coordinates = feature.geometry.coordinates[0];
            // 检查每条边是否与其他非相邻边相交
            for (let i = 0; i < coordinates.length - 1; i++) {
                const line1 = turf.lineString([coordinates[i], coordinates[i + 1]]);

                for (let j = i + 2; j < coordinates.length - 1; j++) {
                    // 跳过相邻的边
                    if (i === 0 && j === coordinates.length - 2) continue;

                    const line2 = turf.lineString([coordinates[j], coordinates[j + 1]]);

                    if (turf.booleanIntersects(line1, line2)) {
                        return true; // 发现自相交
                    }
                }
            }
            return false; // 没有自相交
        },

        /**
         * 初始组件样式
         */
        createStyle() {
            let css = `
            .mapboxgl-control-container{display: none;}
            .project-region-editor,.region-editor-container{position:relative; width: 100%; height: 100%;}
            .region-editor-search{position: absolute; left: 20px; top:20px; z-index: 100;}
            .region-editor-buttons{position: absolute; right: 20px; top:20px; z-index: 100; display: flex; flex-direction: column; align-items: flex-end;}
            .region-editor-buttons .el-button:not(:first-child){margin-top: 5px;}
            `;
            const existingStyles = document.querySelectorAll('style');
            for (let style of existingStyles) {
                if (style.textContent.trim() === css.trim()) {
                    return; // 样式已存在，不需要添加
                }
            }
            let style = document.createElement('style');
            style.appendChild(document.createTextNode(css));
            document.head.appendChild(style);
        }
    },
});